home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
EnigmA Amiga Run 1996 February
/
EnigmA AMIGA RUN 04 (1996)(G.R. Edizioni)(IT)[!][issue 1996-02][Skylink CD III].iso
/
docs
/
corsoguide
/
segnali-7.txt
< prev
next >
Wrap
Text File
|
1992-09-03
|
5KB
|
87 lines
I segnali (signals)
I segnali (da non confondere con quelli di fumo che, se emessi dal vostro
calcolatore sono indice di qualcosa di grave) sono il mezzo a disposizione
di exec per "segnalare" al task che si è verificata una situazione per cui
quest'ultimo aveva chiesto di essere avvertito.
Questo meccanismo è molto importante per un sistema multitasking quale è
l'Amiga; infatti i processi (o task) vengono classificati con dei stati a
seconda del momento; in particolare dato che l'Amiga ha un solo processore,
questo deve essere diviso fra più task simulando più CPU virtuali; per far
questo viene dedicato ad ogni task un determinato quanto di tempo, alla
scadenza del quale il task viene momentaneamente congelato (con i contenuti
dei registri del microprocessore) per attivare un altro task (ciò che viene
definito multitasking pre-emptive); come potete osservare il task può
venire a trovarsi in diverse situazioni e più precisamente 3: attivo
(running), pronto (ready), addormentato (sleeping). Il task è in stato di
attivo quando è effettivamente in esecuzione, in stato pronto quando
attende di essere attivato dato che il microprocessore sta eseguendo un
altro task, ma quello che ci interessa al momento è lo stato di
addormentato; capita sovente infatti, che il programma debba attendere
senza far nulla un evento di I/O (pressione del taso del mouse o della
tastiera ecc.), per cui il tempo messo a sua disposizione verrebbe
totalmente sprecato dato che quest'ultimo potrebbe essere utilizzato da
altri task, ed il s.o. gli ridarebbe il controllo quando si verifica
l'evento di I/O atteso, ed è proprio a questo che serve lo stato di
addormentato; infatti il programma può chiedere di essere momentaneamente
"addormentato" tramite la funzione Wait di exec e verrà risvegliato solo
quando verrà raggiunto da un segnale (che potrà essere spedito dal s.o.
oppure da un altro task per un messaggio); un segnale è identificato da un
particolare bit in una maschera data da una LONG; il ché significa che
possono essere in circolazione al massimo 32 segnali per un task (di cui 16
riservati al s.o.), per cui bisogna innanzitutto chiederne l'uso al s.o. e
liberarlo al più presto; in realtà non capita mai di utilizzare i segnali
direttamente a meno di non voler segnalare un altro task (creato ovviamente
dallo stesso programma) di effettuare una qualsiasi azione e comunque per
la comunicazione fra task si utilizzano normalmente le porte ed i messaggi
che fanno ugualmente uso di questo meccanismo; la funzione importante è
ovviamente Wait che permette al programma di andare in stato di sleeping
ottimizzando così le risorse di sistema; le funzioni per
allocare/deallocare i segnali sono:
NumSegnale = AllocSignal(NumSegnale);
FreeSignal(NumSegnale);
dove NumSegnale è il numero di segnale da allocare (che va da 16 a 31 dato
che i primi 16 sono occupati dal s.o.); AllocSignal alloca e riserva l'uso
del segnale NumSegnale, il valore ritornato vale -1 se non è stato possibile
allocare il segnale, oppure vale il codice del segnale allocato in caso
contrario; FreeSignal rilascia l'uso del segnale precedentemente occupato,
al sistema; c'è la possibiltà quando si alloca un segnale, e conviene
utilizzarla, di non specificare un preciso segnale ma di farsi rilasciare il
primo libero utilizzando come parametro di AllocSignal -1.
Ma la funzione di exec più importante riguardante i segnali, e che la
ritroveremo più avanti, è la funzione Wait che permette di mandare il task
in stato di sleeping in attesa di qualche segnale che lo svegli:
Segnali = Wait(SetSegnali);
dove SetSegnali indica per quali segnali il task deve essere riattivato e il
valore ritornato Segnali (ambedue di tipo LONG) indica quale segnale ha
risvegliato il task; SetSegnali è una maschera a cui ogni segnale di valore
NumSegnale (ritornato da AllocSignal) corrisponde il bit di posizione n,
dove n equivale a NumSegnale (se tale bit è ad 1 Wait attenderà per quel
segnale altrimenti no); questo per permettere di specificare più segnali per
il risveglio di un task, di conseguenza Segnali sarà dello stesso tipo
esempio:
Segnali = Wait(1<<NumSegnale | 4);
if (Segnali & 1<<NumSegnale)
printf("Task risvegliato dal segnale allocato.\n");
Il piccolo esempio pone il task in sleeping per il segnale NumSegnale
allocato in precedenza e per il segnale 2 (4 = 1<<2) del s.o., quindi si
verifica se il segnale che ha risvegliato il task è NumSegnale nel qual caso
stampa un messaggio di conferma. Vi è anche la possibilità di verificare se
un segnale è arrivato senza necessariamente mandare il task in sleeping
tramite questa funzione di exec: SetSignal (vedere i doc per questo);
l'ultima funzione da esaminare riguardo i segnali è Signal che permette al
programma di inviare un qualsiasi segnale ad un task:
Signal(Task,SetSegnali);
dove Task è il puntatore ad una struttura Task che identifica il task a cui
mandare il segnale (vedremo nella prossima puntata la struttura Task) e
SetSegnali è la long tipo quella specificata in Wait contenente i bit dei
segnali da inviare al task.